from py2neo import Graph,Node,Relationship,NodeMatcher,RelationshipMatcher

import json


def connectNeo4j(ip,username,password):

    graph = Graph(ip, name=username, password=password)
    matcher = NodeMatcher(graph)
    rmatcher = RelationshipMatcher(graph)
    graph.delete_all()
    
    return graph,matcher,rmatcher


def init_nodes(nodes):
    for node in nodes:
        print(node)
        '''print(node['fid'])

        print(node['path'])'''
        fid = str(node['fid'])

        path = node['path']
        filename = "temp"

        if(path == "<built-in>" or path == "<scratch space>"):
            filename = path
        else:
            temp = path.split("/")
            filename = temp[len(temp)-1]
        #print(filename)

        #new_node = Node(package_name,ac_label,ac_label_index,name=node_name)
        label = "file"
        new_node = Node(label,filename=filename,fid=fid,path=path)
        filedic[fid] = new_node
        graph.create(new_node)
    return

def init_edges(edges):
    for edge in edges:
        print(edge)
        src = str(edge['startnode'])
        dst = str(edge['endnode'])
        refs = edge['ref']
        #nodesrc = matcher.match(fid=src).first()
        nodesrc = filedic[src]
        for ref in refs:
            ref = str(ref)
            nodedst = matcher.match(refid=ref).first()

            label = "use"
            newrelation_file2ref= Relationship(nodesrc,label,nodedst)

            graph.create(newrelation_file2ref)
        '''
        for depsymbol in depsymbols:
            print(depsymbol)
            qualifiedname = depsymbol['qualifiedname']
            symboltype = depsymbol['symboltype']
            referencetype = depsymbol['referencetype']
            location = depsymbol['location']
            symbolnode = Node(labelsymbol,qualifiedname=qualifiedname,symboltype=symboltype,referencetype=referencetype,location=location)
            graph.create(symbolnode)

            symbollabel = "temp"

            newrelation_src2symbol = Relationship(nodesrc,symbolnode)

            newrelation_symbol2dst = Relationship(symbolnode,nodedst)

            graph.create(newrelation_src2symbol)
            graph.create(newrelation_symbol2dst)
        '''
        '''length = str(len(depsymbol))
        depsymbol = str(depsymbol)
        #print(depsymbol)
        #print(len(depsymbol))
        #print(len)
        node1 = matcher.match(fid=src).first()
        node2 = matcher.match(fid=dst).first()    
        print(src)
        print(dst)
        print(node1)
        print(node2)
        newrelation = Relationship(node1,length,node2,depsymbol=depsymbol)
        graph.create(newrelation)'''
    return


def init_symbolnode(data_symbolnode):
    for node in data_symbolnode:
        print(node)
        '''print(node['fid'])
        print(node['path'])'''
        sid = str(node['sid'])
        qualifiedname = node['qualifiedname']
        symboltype = node['symboltype']
        name = node['name']
        #new_node = Node(package_name,ac_label,ac_label_index,name=node_name)
        label = "symbol"
        new_node = Node(label,qualifiedname=qualifiedname,sid=sid,symboltype=symboltype,name=name)
        symboldic[sid] = new_node
        graph.create(new_node)
    return


def init_refnode(data_refnode):
    for node in data_refnode:
        print(node)
        refid = str(node['refid'])
        sid = str(node['sid'])
        reftype = node['reftype']
        fid = str(node['fid'])

        location = node['location']
        #new_node = Node(package_name,ac_label,ac_label_index,name=node_name)
        label = "ref"
        nodesymbol = symboldic[sid]
        nodefile = filedic[fid]

        name = nodesymbol['name']
        ref_node = Node(label,refid=refid,location=location,reftype=reftype,name=name)
        graph.create(ref_node)

        #nodesymbol = matcher.match(sid=sid).first()
        #nodefile = matcher.match(fid=fid).first()

        symbolreflabel = "symbolref"
        reffilelabel = "located_in"

        #print(nodesymbol)
        #print(ref_node)
        #print(nodefile)

        newrelation_symbol2ref = Relationship(nodesymbol,symbolreflabel,ref_node)
        newrelation_ref2file = Relationship(ref_node,reffilelabel,nodefile)

        graph.create(newrelation_symbol2ref)
        graph.create(newrelation_ref2file)
    return


if __name__ == "__main__":
    filedic = {}
    symboldic = {}
    (graph,matcher,rmatcher) = connectNeo4j('http://localhost:7474',"neo4j","123456")

    data_node = json.load(open("filenode.json","r"))
    init_nodes(data_node)

    data_symbolnode = json.load(open("symbolnode.json","r"))
    init_symbolnode(data_symbolnode)

    data_refnode = json.load(open("refnode.json","r"))
    init_refnode(data_refnode)

    data_edge = json.load(open("edge.json","r"))
    init_edges(data_edge)

#    MATCH (a:symbol{name:'__DECL_SIMD_expl'}) MATCH p = (a)-[*..1]-(b:ref)-[*..1]->(c:file) RETURN p LIMIT 25
